#include "lib.h"

#include "getrand.h"
#include "kenogame.h"
#include "kenocard.h"
#include "kenobet.h"
#include "kenopayout.h"
#include "opts.h"

#define MAXIMUM_GAME_PAYOUT (25000000)

enum Outcomes
{
	O_PLAYER_WON,
	O_PLAYER_LOST,
};

KenoGame::KenoGame(KenoPayout* payout)
{
	m_payout = payout;
	m_bet = (KenoBet *)0;

#ifdef FORCED_KENO
	m_forcedResults = 0;
#endif
}

KenoGame::~KenoGame()
{
//	delete m_bet;
//	m_bet = (KenoBet *)0;
}

 void
KenoGame::send()
{
	//
	// This message is contained within another message
	// (don't call msgStart()/msgEnd()).
	//
}

bool8 
KenoGame::PlayCard(KenoCard &card)
{
	if(m_bet && m_bet->PlayCard(card))
		return true;
	else
		return false;
}

int32
KenoGame::findPayout(int32 picks, int32 catches)
{
	return m_payout->GetPayout(picks, catches);
}

int32
KenoGame::findCardPayout(KenoCard *card, int32 *picks)
{
	int32 catches = 0;

	for(int32 i = 0; i < card->GetNumPicks(); i++)
	{
		for(int32 j = 0; j < 20; j++)
		{
			if(card->GetPick(i) == picks[j])
				catches++;
		}
	}
//	DEBUGMSG(("Picks - %d, catches - %d",card->GetNumPicks(), catches));

	return card->GetCost() * findPayout(card->GetNumPicks(), catches);
}

int32
KenoGame::findPayout(KenoBet *bet, int32 *picks)
{
	int32 totalpayout = 0;
	for(int32 card = 0; card < bet->GetNumCards(); card++)
	{
		if(bet->GetCard(card)->IsValid())
		{
			totalpayout += findCardPayout(bet->GetCard(card), picks);
		}
	}

	if(totalpayout > MAXIMUM_GAME_PAYOUT)
		totalpayout = MAXIMUM_GAME_PAYOUT;

	return totalpayout;
}

int32
KenoGame::findTotalCost(KenoBet *bet)
{
	int32 totalcost = 0;
	for(int32 i = 0; i < bet->GetNumCards(); i++)
	{
		totalcost += bet->GetCard(i)->GetCost();
	}
	return totalcost;
}

bool8 
KenoGame::PlayGame(KenoBet *bet, int32 *out_payout, int32 *picks)
{
	int32 numpicks = 0;
	bool8 found = false;

#ifdef FORCED_KENO
	// CSN-12127: Check for forced results only if Testing is enabled
	bool8 forcedLoaded = false;
	if (ServerOpts::bAllowTesting && m_forcedResults && !m_forcedResults->isEmpty())
	{
		forcedLoaded = true;
		m_forcedResults->resetIndex();
	}
#endif

	while (numpicks < 20)
	{
#ifndef FORCED_KENO
		int32 p = getrand() % 80;
#else
		// Try to get a forced result
		int32 p = 0;
		bool8 forced = false;

		if (forcedLoaded && numpicks <= m_forcedResults->getTotal())
			forced = m_forcedResults->getNext(p);

		// Generate a random result if a forced one wasn't retrieved
		if (!forced)
			p = getrand() % 80;
#endif

		// Ensure that the new result hasn't been already chosen
		found = false;
		for (int32 i = 0; i < numpicks; i++)
		{
			if (picks[i] == p)
				found = true;
		}
		if (!found)
		{
			picks[numpicks++] = p;
		}
	}

	int32 payout = findPayout(bet, picks);
	*out_payout  = payout;

	return true;
}

bool8 
KenoGame::PlaceBet(KenoBet *bet)
{
	m_bet = bet;
	return true;
}

#ifdef FORCED_KENO
void KenoGame::setForcedResults(GameForcedResults* forcedResults)
{
	m_forcedResults = forcedResults;
}
#endif
